package org.light.limitedverb;

import java.util.ArrayList;
import java.util.List;

import org.light.core.Writeable;
import org.light.domain.Domain;
import org.light.domain.Method;
import org.light.domain.Signature;
import org.light.domain.Statement;
import org.light.domain.Type;
import org.light.domain.Var;
import org.light.generator.NamedStatementGenerator;
import org.light.generator.NamedStatementListGenerator;
import org.light.utils.InterVarUtil;
import org.light.utils.StringUtil;
import org.light.utils.TableStringUtil;
import org.light.utils.WriteableUtil;

public class CountActiveRecords extends NoControllerVerb {

	@Override
	public Method generateDaoImplMethod(){	
		Method method = new Method();
		method.setStandardName("countActive"+StringUtil.capFirst(this.domain.getStandardName())+"Records");
		method.setReturnType(new Type("Integer"));
		method.addAdditionalImport("java.sql.Connection");
		method.addAdditionalImport(this.domain.getPackageToken()+"."+this.domain.getDomainSuffix()+"."+this.domain.getCapFirstDomainNameWithSuffix());
		method.addSignature(new Signature(1,"connection",new Type("Connection","java.sql"),"java.sql"));
		method.setThrowException(true);
		
		List<Writeable> list = new ArrayList<Writeable>();
		Var recordCount = new Var("recordcount",new Type("Integer"));
		Var countNum = new Var("countNum",new Type("Integer"));
		list.add(NamedStatementGenerator.getCountActiveRecordSqlStatement(100L, 2, domain, InterVarUtil.DB.query, recordCount, countNum));
		list.add(NamedStatementGenerator.getPrepareStatement(200L,2,InterVarUtil.DB.ps, InterVarUtil.DB.query, InterVarUtil.DB.connection));
		list.add(NamedStatementGenerator.getPrepareStatementExcuteQuery(300L,2, InterVarUtil.DB.result, InterVarUtil.DB.ps));
		list.add(new Statement(400,2,recordCount.generateTypeVarString() +" = 0;"));
		list.add(NamedStatementGenerator.getResultSetWhileNextLoopHead(500L,2, InterVarUtil.DB.result));		
		list.add(NamedStatementGenerator.getRecordCountVarTypeFromResultSet(800L,3,domain, InterVarUtil.DB.result,recordCount,countNum));
		list.add(new Statement(900,2,"}"));
		list.add(NamedStatementGenerator.getReturnInt(1200,2, recordCount));

		method.setMethodStatementList(WriteableUtil.merge(list));
		return method;
	}

	@Override
	public String generateDaoImplMethodString() {
		Method m = this.generateDaoImplMethod();
		String s = m.generateMethodString();
		return s;
	}

	@Override
	public String generateDaoImplMethodStringWithSerial() {
		Method m = this.generateDaoImplMethod();
		m.setContent(m.generateMethodContentStringWithSerial());
		m.setMethodStatementList(null);
		return m.generateMethodString();
	}

	@Override
	public Method generateDaoMethodDefinition() {
		Method method = new Method();
		method.setStandardName("countActive"+this.domain.getCapFirstDomainName()+"Records");
		method.setReturnType(new Type("Integer"));
		method.addSignature(new Signature(1,InterVarUtil.DB.connection.getVarName(),InterVarUtil.DB.connection.getVarType()));
		method.addAdditionalImport(this.domain.getPackageToken()+"."+this.domain.getDomainSuffix()+"."+this.domain.getCapFirstDomainNameWithSuffix());
		method.setThrowException(true);
		return method;
	}

	@Override
	public String generateDaoMethodDefinitionString() {
		return generateDaoMethodDefinition().generateMethodDefinition();
	}

	@Override
	public Method generateServiceMethodDefinition() {
		Method method = new Method();
		method.setStandardName("countActive"+this.domain.getCapFirstDomainName()+"Records");
		method.setReturnType(new Type("Integer"));
		method.addAdditionalImport(this.domain.getPackageToken()+"."+this.domain.getDomainSuffix()+"."+this.domain.getCapFirstDomainNameWithSuffix());
		method.setThrowException(true);
		
		return method;
	}

	@Override
	public String generateServiceMethodDefinitionString() {
		return generateServiceMethodDefinition().generateMethodDefinition();
	}

	@Override
	public Method generateServiceImplMethod() {
		Method method = new Method();
		method.setStandardName("countActive"+this.domain.getCapFirstDomainName()+"Records");
		method.setReturnType(new Type("Integer"));
		method.addAdditionalImport(this.domain.getPackageToken()+"."+this.domain.getDomainSuffix()+"."+this.domain.getCapFirstDomainNameWithSuffix());
		method.addAdditionalImport(this.domain.getPackageToken()+"."+this.domain.getDaoSuffix()+"."+this.domain.getStandardName()+"Dao");
		method.addAdditionalImport(this.domain.getPackageToken()+"."+this.domain.getServiceSuffix()+"."+this.domain.getStandardName()+"Service");
		method.setThrowException(true);
		method.addMetaData("Override");
		
		Method daomethod = this.generateDaoMethodDefinition();		
		List<Writeable> list = new ArrayList<Writeable>();
		list.add(NamedStatementListGenerator.generateServiceImplReturnInt(1000L, 2, InterVarUtil.DB.connection, InterVarUtil.DB.dbconf, this.domain, InterVarUtil.DB.dao, daomethod));
		method.setMethodStatementList(WriteableUtil.merge(list));

		return method;
	}

	@Override
	public String generateServiceImplMethodString(){
		return generateServiceImplMethod().generateMethodString();
	}

	@Override
	public String generateServiceImplMethodStringWithSerial() {
		Method m = this.generateServiceImplMethod();
		m.setContent(m.generateMethodContentStringWithSerial());
		m.setMethodStatementList(null);
		return m.generateMethodString();
	}
	
	public CountActiveRecords(Domain domain){
		super();
		this.domain = domain;
		this.verbName = "countActive"+this.domain.getCapFirstDomainName()+"Records";
	}
	
	public CountActiveRecords(){
		super();
	}

	@Override
	public Method generateDummyDaoImplMethod() throws Exception {
		if (this.denied)
			return null;
		else {
			Method method = new Method();
			method.setStandardName(StringUtil.lowerFirst(this.getVerbName()));
			method.setReturnType(new Type("Integer"));
			method.addAdditionalImport(this.domain.getPackageToken() + "." + this.domain.getDomainSuffix() + "."
					+ this.domain.getCapFirstDomainNameWithSuffix());
			method.setThrowException(true);
			
			List<Writeable> sList = new ArrayList<Writeable>();
			sList.add(new Statement(1000L,2," Integer count = 0;"));
			sList.add(new Statement(2000L,2,"for ("+this.domain.getCapFirstDomainNameWithSuffix()+" "+this.domain.getLowerFirstDomainName()+" : db) {"));
			sList.add(new Statement(3000L,3,"if ("+this.domain.getLowerFirstDomainName()+".get"+this.domain.getActive().getCapFirstFieldName()+"().equals("+this.domain.getDomainActiveInteger()+")) count++;"));
			sList.add(new Statement(4000L,2,"}"));
			sList.add(new Statement(5000L,2,"return count;"));
			method.setMethodStatementList(WriteableUtil.merge(sList));
			return method;
		}
	}

	@Override
	public Method generateDummyServiceImplMethod() throws Exception {
		if (this.denied)
			return null;
		else {
			Method method = new Method();
			method.setStandardName(StringUtil.lowerFirst(this.getVerbName()));
			method.setReturnType(new Type("Integer"));
			method.setThrowException(true);
			method.addAdditionalImport("java.util.List");
			method.addAdditionalImport(this.domain.getPackageToken() + "." + this.domain.getDomainSuffix() + "."
					+ this.domain.getCapFirstDomainNameWithSuffix());
			method.addAdditionalImport(this.domain.getPackageToken() + "." + this.domain.getDaoSuffix() + "."
					+ this.domain.getStandardName() + "Dao");
			method.addAdditionalImport(this.domain.getPackageToken() + "." + this.domain.getServiceSuffix() + "."
					+ this.domain.getStandardName() + "Service");
			method.addMetaData("Override");

			List<Writeable> list = new ArrayList<Writeable>();
			Method daomethod = this.generateDummyDaoMethodDefinition();
			list.add(new Statement(1000L,2, "return " + daomethod.generateStandardServiceImplCallString(InterVarUtil.DB.dao.getVarName())+";"));
			method.setMethodStatementList(WriteableUtil.merge(list));
			return method;
		}
	}

	@Override
	public Method generateDummyDaoMethodDefinition() throws Exception {
		if (this.denied)
			return null;
		else {
			Method method = new Method();
			method.setStandardName(StringUtil.lowerFirst(this.getVerbName()));
			method.setReturnType(new Type("Integer"));
			method.addAdditionalImport(this.domain.getPackageToken() + "." + this.domain.getDomainSuffix() + "."
					+ this.domain.getCapFirstDomainNameWithSuffix());
			method.setThrowException(true);
			return method;
		}
	}
}
